package com.java.simple.study.juc.p7;

import com.java.simple.study.tool.Sleeper;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author zhoujunlin
 * @date 2022年10月13日 22:09
 * @desc
 */
@Slf4j(topic = "c.TestCountDownLatch")
public class TestCountDownLatch {

    public static void main(String[] args) throws InterruptedException {
        //test1();
        //test2();
        test3();
    }

    public static void test3() throws InterruptedException {
        AtomicInteger num = new AtomicInteger(0);
        //可以给线程命名的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10, r -> new Thread(r, "t" + num.getAndIncrement()));

        CountDownLatch countDownLatch = new CountDownLatch(10);
        String[] all = new String[10];
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            int x = i;
            executorService.submit(() -> {
                for (int j = 0; j <= 100; j++) {
                    Sleeper.sleep(random.nextDouble() + 0.2);
                    all[x] = Thread.currentThread().getName() + "(" + (j + "%") + ")";
                    System.out.print("\r" + Arrays.toString(all));
                }
                countDownLatch.countDown();
            });
        }

        countDownLatch.await();
        System.out.println("\n游戏开始");
        executorService.shutdown();
    }

    private static void test2() {
        CountDownLatch countDownLatch = new CountDownLatch(3);
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        executorService.submit(() -> {
            log.debug("begin...");
            Sleeper.sleep(1);
            countDownLatch.countDown();
            log.debug("end...{}", countDownLatch.getCount());
        });

        executorService.submit(() -> {
            log.debug("begin...");
            Sleeper.sleep(1.5);
            countDownLatch.countDown();
            log.debug("end...{}", countDownLatch.getCount());
        });

        executorService.submit(() -> {
            log.debug("begin...");
            Sleeper.sleep(2);
            countDownLatch.countDown();
            log.debug("end...{}", countDownLatch.getCount());
        });

        executorService.submit(() -> {
            try {
                log.debug("waiting...");
                countDownLatch.await();
                log.debug("wait end...{}", countDownLatch.getCount());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }

    private static void test1() throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(3);
        new Thread(() -> {
            log.debug("begin...");
            Sleeper.sleep(1);
            countDownLatch.countDown();
            log.debug("end...{}", countDownLatch.getCount());
        }, "t1").start();

        new Thread(() -> {
            log.debug("begin...");
            Sleeper.sleep(2);
            countDownLatch.countDown();
            log.debug("end...{}", countDownLatch.getCount());
        }, "t2").start();

        new Thread(() -> {
            log.debug("begin...");
            Sleeper.sleep(1.5);
            countDownLatch.countDown();
            log.debug("end...{}", countDownLatch.getCount());
        }, "t3").start();

        log.debug("waiting...");
        countDownLatch.await();
        log.debug("wait end...");
    }


}
